﻿using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OrBitDataModule.Base;
using System.Reflection;
using System.Windows.Forms;
using System.Data;

namespace OrBitDataAcquisition.Common
{
    internal class Tools
    {
        /// <summary>
        /// 转换Image为Icon
        /// </summary>
        /// <param name="image">要转换为图标的Image对象</param>
        /// <param name="nullTonull">当image为null时是否返回null。false则抛空引用异常</param>
        /// <exception cref="ArgumentNullException" />
        public static Icon ConvertToIcon(Image image, bool nullTonull = false)
        {
            if (image == null)
            {
                if (nullTonull) { return null; }
            }
            using (MemoryStream msImg = new MemoryStream(), msIco = new MemoryStream())
            {
                image.Save(msImg, ImageFormat.Png);
                using (var bin = new BinaryWriter(msIco))
                {
                    bin.Write((short)0);
                    bin.Write((short)1);
                    bin.Write((short)1);

                    bin.Write((byte)image.Width);
                    bin.Write((byte)image.Height);
                    bin.Write((byte)0);
                    bin.Write((byte)0);
                    bin.Write((short)0);
                    bin.Write((short)32);
                    bin.Write((int)msImg.Length);
                    bin.Write(22);

                    bin.Write(msImg.ToArray());

                    bin.Flush();
                    bin.Seek(0, SeekOrigin.Begin);
                    return new Icon(msIco);
                }
            }
        }

        /// <summary>
        /// 获取dll目录下所有dll的任务清单
        /// </summary>
        /// <returns></returns>
        public async static Task<DataTable> GetAssemblyListAsync()
        {
            DataTable dataTable = new DataTable();
            await Task.Run(() =>
             {
                 dataTable.Columns.Add("TaskName", typeof(string));
                 dataTable.Columns.Add("TypeName", typeof(string));
                 dataTable.Columns.Add("DllFileName", typeof(string));

                 string directoryPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "dll");
                 string baseTypeName = typeof(DataTaskBase).FullName;
                 string[] dllFiles = Directory.GetFiles(directoryPath, "*.dll");
                 foreach (string dllFile in dllFiles)
                 {
                     if (Path.GetExtension(dllFile).Equals(".dll", StringComparison.OrdinalIgnoreCase))
                     {
                         using (FileStream fs = new FileStream(dllFile, FileMode.Open, FileAccess.Read))
                         {
                             using (BinaryReader br = new BinaryReader(fs))
                             {
                                 byte[] bytes = br.ReadBytes((int)fs.Length);
                                 Type[] types = Assembly.Load(bytes).GetTypes();
                                 foreach (Type type in types)
                                 {
                                     if (type.BaseType?.FullName == baseTypeName)
                                     {
                                         var obj = Activator.CreateInstance(type) as DataTaskBase;
                                         DataRow dr = dataTable.NewRow();
                                         dr["TaskName"] = obj.TaskName;
                                         dr["TypeName"] = type.FullName;
                                         dr["DllFileName"] = dllFile;
                                         dataTable.Rows.Add(dr);
                                     }
                                 }
                             }
                         }
                     }
                 }
             });
            return dataTable;
        }
    }
}